package com.native_video_cache.native_video_cache;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.EventChannel.EventSink;
import io.flutter.plugin.common.EventChannel.StreamHandler;

import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.ScheduledFuture;

import com.danikula.videocache.HttpProxyCacheServer;
import com.danikula.videocache.CacheListener;
import com.danikula.videocache.file.FileNameGenerator;
import com.danikula.videocache.headers.HeaderInjector;

/** NativeVideoCachePlugin */
public class NativeVideoCachePlugin
        implements FlutterPlugin, NativeVideoCacheApiGenerated.NativeVideoCacheApi, MethodCallHandler, StreamHandler {

    private static final String TAG = "NativeVideoCachePlugin";
    private MethodChannel channel;
    private Context context;
    private HttpProxyCacheServer proxyServer;
    private final ConcurrentHashMap<String, Set<CacheListener>> progressListeners = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Set<CacheListener>> statusListeners = new ConcurrentHashMap<>();
    private ScheduledExecutorService scheduledExecutor;
    private final Handler mainHandler = new Handler(Looper.getMainLooper());
    private NativeVideoCacheApiGenerated.NativeVideoCacheCacheListener flutterCacheListener;

    // 缓存状态跟踪
    private final ConcurrentHashMap<String, NativeVideoCacheApiGenerated.CacheStatus> cacheStatus = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Double> cacheProgress = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, ScheduledFuture<?>> monitoringTasks = new ConcurrentHashMap<>();

    // EventChannel for cache events
    private EventChannel eventChannel;
    private EventSink eventSink;

    @Override
    public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {
        channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "native_video_cache");
        channel.setMethodCallHandler(this);
        context = flutterPluginBinding.getApplicationContext();

        // 设置Pigeon API
        NativeVideoCacheApiGenerated.NativeVideoCacheApi.setUp(flutterPluginBinding.getBinaryMessenger(), this);

        // 设置EventChannel
        eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "native_video_cache/cache_events");
        eventChannel.setStreamHandler(this);
    }

    @Override
    public void onMethodCall(MethodCall call, Result result) {
        if (call.method.equals("getPlatformVersion")) {
            result.success("Android " + android.os.Build.VERSION.RELEASE);
        } else {
            result.notImplemented();
        }
    }

    @Override
    public void onDetachedFromEngine(FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
        NativeVideoCacheApiGenerated.NativeVideoCacheApi.setUp(binding.getBinaryMessenger(), null);
        if (eventChannel != null) {
            eventChannel.setStreamHandler(null);
            eventChannel = null;
        }
        cleanup();
    }

    @Override
    public void initialize(NativeVideoCacheApiGenerated.CacheConfig config,
            NativeVideoCacheApiGenerated.VoidResult result) {
        Log.d(TAG, "Initializing NativeVideoCachePlugin with config: " + config.toString());
        try {
            // 停止现有的代理服务器
            if (proxyServer != null) {
                Log.d(TAG, "Shutting down existing proxy server.");
                proxyServer.shutdown();
            }

            // 创建缓存目录
            String cacheDirectory = config.getCacheDirectory();
            if (cacheDirectory == null) {
                cacheDirectory = context.getCacheDir() + "/video_cache";
            }
            Log.d(TAG, "Cache directory: " + cacheDirectory);
            File cacheDir = new File(cacheDirectory);
            if (!cacheDir.exists()) {
                cacheDir.mkdirs();
            }

            // 配置代理服务器
            HttpProxyCacheServer.Builder builder = new HttpProxyCacheServer.Builder(context)
                    .cacheDirectory(cacheDir);

            // 设置最大缓存大小
            Long maxCacheSize = config.getMaxCacheSize();
            if (maxCacheSize != null) {
                builder.maxCacheSize(maxCacheSize);
                Log.d(TAG, "Max cache size set to: " + maxCacheSize);
            } else {
                builder.maxCacheSize(1024L * 1024L * 1024L); // 默认1GB
                Log.d(TAG, "Max cache size set to default: 1GB");
            }

            // 设置超时时间
            final Long connectTimeout = config.getConnectTimeout();
            final Long readTimeout = config.getReadTimeout();
            if (connectTimeout != null || readTimeout != null) {
                Log.d(TAG, "Setting timeouts - Connect: " + connectTimeout + "ms, Read: " + readTimeout + "ms");
                builder.headerInjector(new HeaderInjector() {
                    @Override
                    public Map<String, String> addHeaders(String url) {
                        Map<String, String> headers = new HashMap<>();
                        if (connectTimeout != null) {
                            headers.put("Connect-Timeout", connectTimeout.toString());
                        }
                        if (readTimeout != null) {
                            headers.put("Read-Timeout", readTimeout.toString());
                        }
                        return headers;
                    }
                });
            }

            // 设置文件名生成器（使用URL hash）
            builder.fileNameGenerator(new FileNameGenerator() {
                @Override
                public String generate(String url) {
                    String extension = "mp4";
                    int lastDotIndex = url.lastIndexOf('.');
                    if (lastDotIndex > 0 && lastDotIndex < url.length() - 1) {
                        extension = url.substring(lastDotIndex + 1);
                    }
                    String fileName = String.valueOf(url.hashCode()) + "." + extension;
                    Log.d(TAG, "Generated filename for " + url + ": " + fileName);
                    return fileName;
                }
            });

            proxyServer = builder.build();
            Log.d(TAG, "Proxy server built successfully.");

            // 初始化调度器
            if (scheduledExecutor == null || scheduledExecutor.isShutdown()) {
                scheduledExecutor = Executors.newScheduledThreadPool(2);
                Log.d(TAG, "ScheduledExecutorService initialized.");
            }

            result.success();
            Log.d(TAG, "Initialization successful.");
        } catch (Exception e) {
            Log.e(TAG, "Initialization failed", e);
            result.error(e);
        }
    }

    @Override
    public void getProxyUrl(String originalUrl, NativeVideoCacheApiGenerated.Result<String> result) {
        Log.d(TAG, "getProxyUrl called for: " + originalUrl);
        try {
            if (proxyServer != null) {
                String proxyUrl = proxyServer.getProxyUrl(originalUrl);
                Log.d(TAG, "Generated proxy URL: " + proxyUrl);
                // 移除重复的监听启动，统一在startCache中处理
                result.success(proxyUrl);
            } else {
                Log.e(TAG, "Proxy server not initialized in getProxyUrl.");
                result.error(new RuntimeException("代理服务器未初始化"));
            }
        } catch (Exception e) {
            Log.e(TAG, "Error in getProxyUrl", e);
            result.error(e);
        }
    }

    @Override
    public void startCache(String url, NativeVideoCacheApiGenerated.VoidResult result) {
        Log.d(TAG, "startCache called for: " + url);
        try {
            // AndroidVideoCache会在访问代理URL时自动开始缓存
            // 这里我们主动触发缓存
            if (proxyServer != null) {
                String proxyUrl = proxyServer.getProxyUrl(url);
                Log.d(TAG, "Starting cache for " + url + " using proxy URL: " + proxyUrl);

                // 设置初始缓存状态
                if (flutterCacheListener != null) {
                    Log.d(TAG, "Notifying Flutter: status CACHING, progress 0.0 for " + url);
                    flutterCacheListener.onCacheStatusChanged(url, NativeVideoCacheApiGenerated.CacheStatus.CACHING);
                    flutterCacheListener.onCacheProgressChanged(url, 0.0);
                }

                // 创建一个虚拟请求来触发缓存
                if (scheduledExecutor != null && !scheduledExecutor.isShutdown()) {
                    Log.d(TAG, "Submitting task to trigger caching for " + url);
                    scheduledExecutor.execute(new Runnable() {
                        @Override
                        public void run() {
                            Log.d(TAG, "Executing virtual request for " + proxyUrl);
                            try {
                                java.net.URL urlObj = new java.net.URL(proxyUrl);
                                java.net.URLConnection connection = urlObj.openConnection();
                                connection.connect();
                                connection.getInputStream().close();
                                Log.d(TAG, "Virtual request for " + proxyUrl + " completed.");
                            } catch (Exception e) {
                                Log.w(TAG, "Virtual request for " + proxyUrl
                                        + " failed. This might be expected if caching starts.", e);
                                // 忽略连接异常，主要目的是触发缓存
                            }
                        }
                    });
                } else {
                    Log.w(TAG, "ScheduledExecutorService not available to trigger caching for " + url);
                }
                startCacheMonitoring(url);
                result.success();
                Log.d(TAG, "startCache for " + url + " completed.");
            } else {
                Log.e(TAG, "Proxy server not initialized in startCache.");
                result.error(new RuntimeException("代理服务器未初始化"));
            }
        } catch (Exception e) {
            Log.e(TAG, "Error in startCache for " + url, e);
            result.error(e);
        }
    }

    @Override
    public void stopCache(String url, NativeVideoCacheApiGenerated.VoidResult result) {
        Log.d(TAG, "stopCache called for: " + url);
        try {
            // AndroidVideoCache没有直接停止缓存的方法
            // 我们只能停止监听和清理状态
            stopCacheMonitoring(url);
            cacheStatus.remove(url);
            cacheProgress.remove(url);
            Log.d(TAG, "Cache monitoring stopped and status cleared for " + url);
            result.success();
        } catch (Exception e) {
            Log.e(TAG, "Error in stopCache for " + url, e);
            result.error(e);
        }
    }

    @Override
    public void getCacheInfo(String url,
            NativeVideoCacheApiGenerated.Result<NativeVideoCacheApiGenerated.CacheInfo> result) {
        Log.d(TAG, "getCacheInfo called for: " + url);
        try {
            boolean isCached = (proxyServer != null) ? proxyServer.isCached(url) : false;
            Log.d(TAG, "Is " + url + " cached? " + isCached);
            NativeVideoCacheApiGenerated.CacheStatus status = isCached ? NativeVideoCacheApiGenerated.CacheStatus.CACHED
                    : cacheStatus.getOrDefault(url, NativeVideoCacheApiGenerated.CacheStatus.NONE);
            double progress = isCached ? 1.0 : cacheProgress.getOrDefault(url, 0.0);
            Log.d(TAG, "Cache status for " + url + ": " + status + ", progress: " + progress);

            // 获取缓存文件大小
            File cacheFile = getCacheFile(url);
            long cachedSize = (cacheFile != null && cacheFile.exists()) ? cacheFile.length() : 0L;
            long totalSize = cachedSize; // AndroidVideoCache 没有提供总大小信息

            NativeVideoCacheApiGenerated.CacheInfo cacheInfo = new NativeVideoCacheApiGenerated.CacheInfo.Builder()
                    .setOriginalUrl(url)
                    .setStatus(status)
                    .setProgress(progress)
                    .setCachedSize(cachedSize)
                    .setTotalSize(totalSize)
                    .setErrorMessage(null)
                    .build();

            result.success(cacheInfo);
        } catch (Exception e) {
            result.error(e);
        }
    }

    @Override
    public void clearAllCache(NativeVideoCacheApiGenerated.VoidResult result) {
        try {
            // 清理缓存目录
            File cacheDir = new File(context.getCacheDir(), "video_cache");
            if (cacheDir.exists()) {
                deleteRecursively(cacheDir);
                cacheDir.mkdirs();
            }

            // 清理状态
            cacheStatus.clear();
            cacheProgress.clear();

            result.success();
        } catch (Exception e) {
            result.error(e);
        }
    }

    @Override
    public void clearCache(String url, NativeVideoCacheApiGenerated.VoidResult result) {
        try {
            File cacheFile = getCacheFile(url);
            if (cacheFile != null && cacheFile.exists()) {
                cacheFile.delete();
            }

            // 清理状态
            cacheStatus.remove(url);
            cacheProgress.remove(url);

            result.success();
        } catch (Exception e) {
            result.error(e);
        }
    }

    @Override
    public void getTotalCacheSize(NativeVideoCacheApiGenerated.Result<Long> result) {
        try {
            File cacheDir = new File(context.getCacheDir(), "video_cache");
            long totalSize = 0L;
            if (cacheDir.exists()) {
                totalSize = calculateDirectorySize(cacheDir);
            }
            result.success(totalSize);
        } catch (Exception e) {
            result.error(e);
        }
    }

    @Override
    public void isCached(String url, NativeVideoCacheApiGenerated.Result<Boolean> result) {
        try {
            boolean cached = (proxyServer != null) ? proxyServer.isCached(url) : false;
            result.success(cached);
        } catch (Exception e) {
            result.error(e);
        }
    }

    @Override
    public void setCacheListener() {
        // 设置Flutter缓存监听器
        Log.d(TAG, "setCacheListener called.");
        flutterCacheListener = new NativeVideoCacheApiGenerated.NativeVideoCacheCacheListener() {
            @Override
            public void onCacheProgressChanged(String url, Double progress) {
                Log.d(TAG, "onCacheProgressChanged (to Flutter) for " + url + ": " + progress);
                // 在主线程中通知Flutter
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        cacheProgress.put(url, progress);
                        // 通过EventChannel发送进度事件
                        Map<String, Object> data = new HashMap<>();
                        data.put("progress", progress);
                        sendCacheEvent("progress", url, data);
                    }
                });
            }

            @Override
            public void onCacheStatusChanged(String url, NativeVideoCacheApiGenerated.CacheStatus status) {
                Log.d(TAG, "onCacheStatusChanged (to Flutter) for " + url + ": " + status);
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        cacheStatus.put(url, status);
                        // 通过EventChannel发送状态事件
                        Map<String, Object> data = new HashMap<>();
                        data.put("status", status.ordinal());
                        sendCacheEvent("status", url, data);
                    }
                });
            }

            @Override
            public void onCacheError(String url, String error) {
                Log.d(TAG, "onCacheError (to Flutter) for " + url + ": " + error);
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        cacheStatus.put(url, NativeVideoCacheApiGenerated.CacheStatus.ERROR);
                        // 通过EventChannel发送错误事件
                        Map<String, Object> data = new HashMap<>();
                        data.put("error", error);
                        sendCacheEvent("error", url, data);
                    }
                });
            }
        };
    }

    @Override
    public void removeCacheListener() {
        Log.d(TAG, "removeCacheListener called.");
        flutterCacheListener = null;
        progressListeners.clear();
        statusListeners.clear();
    }

    private void startCacheMonitoring(String url) {
        Log.d(TAG, "startCacheMonitoring for: " + url);
        // 先停止旧的监控任务（如果存在）
        stopCacheMonitoring(url);

        if (scheduledExecutor != null && !scheduledExecutor.isShutdown()) {
            // 先移除旧的监听器，避免重复添加 (虽然AndroidVideoCache本身没有这个机制，但我们的包装器需要)
            // KTVHTTPCache有此问题，AndroidVideoCache行为不同，这里主要是确保我们的状态一致性
            Log.d(TAG, "Scheduling cache monitoring task for " + url);
            ScheduledFuture<?> task = scheduledExecutor.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    // Log.d(TAG, "Cache monitoring task running for " + url);
                    try {
                        boolean isCached = (proxyServer != null) ? proxyServer.isCached(url) : false;
                        double currentProgress = cacheProgress.getOrDefault(url, 0.0);
                        NativeVideoCacheApiGenerated.CacheStatus currentStatus = cacheStatus.getOrDefault(url,
                                NativeVideoCacheApiGenerated.CacheStatus.NONE);

                        // Log.d(TAG, "Monitoring " + url + ": isCached=" + isCached + ",
                        // currentProgress=" + currentProgress + ", currentStatus=" + currentStatus);

                        if (isCached) {
                            // 缓存完成
                            if (currentStatus != NativeVideoCacheApiGenerated.CacheStatus.CACHED) {
                                Log.d(TAG, "Monitoring " + url + ": Now fully cached. Progress: 1.0, Status: CACHED");
                                if (flutterCacheListener != null) {
                                    flutterCacheListener.onCacheStatusChanged(url,
                                            NativeVideoCacheApiGenerated.CacheStatus.CACHED);
                                    flutterCacheListener.onCacheProgressChanged(url, 1.0);
                                }
                            }
                        } else {
                            // 检查是否在缓存中 (通过文件是否存在和大小变化来模拟)
                            File cacheFile = getCacheFile(url);
                            if (cacheFile != null && cacheFile.exists() && cacheFile.length() > 0) {
                                if (currentStatus != NativeVideoCacheApiGenerated.CacheStatus.CACHING
                                        && currentStatus != NativeVideoCacheApiGenerated.CacheStatus.CACHED) {
                                    Log.d(TAG, "Monitoring " + url
                                            + ": Detected active caching (file exists). Status: CACHING");
                                    if (flutterCacheListener != null) {
                                        flutterCacheListener.onCacheStatusChanged(url,
                                                NativeVideoCacheApiGenerated.CacheStatus.CACHING);
                                    }
                                }
                                // 简单的进度估算（实际应该基于HTTP Content-Length，但AndroidVideoCache不易获取）
                                // 这里我们不能准确计算进度，因为AndroidVideoCache不直接暴露总文件大小
                                // 我们可以发送一个通用的"正在缓存"状态，或者尝试估算，但可能不准确
                                // 暂时不更新具体进度，只更新状态。或者，如果proxyServer.isCached为false但文件存在，我们可以假设它正在缓存。
                                double newProgressEstimate = calculateApproximateProgress(url, cacheFile);
                                if (newProgressEstimate > currentProgress && newProgressEstimate < 1.0) {
                                    Log.d(TAG, "Monitoring " + url + ": Approx. progress updated to "
                                            + newProgressEstimate);
                                    if (flutterCacheListener != null) {
                                        flutterCacheListener.onCacheProgressChanged(url, newProgressEstimate);
                                    }
                                }

                            } else if (currentStatus != NativeVideoCacheApiGenerated.CacheStatus.NONE
                                    && currentStatus != NativeVideoCacheApiGenerated.CacheStatus.ERROR) {
                                // 文件不存在，但之前不是NONE或ERROR，可能缓存被清除了或未开始
                                // Log.d(TAG, "Monitoring " + url + ": Cache file does not exist or is empty.
                                // Resetting status to NONE.");
                                // if (flutterCacheListener != null) {
                                // flutterCacheListener.onCacheStatusChanged(url,
                                // NativeVideoCacheApiGenerated.CacheStatus.NONE);
                                // flutterCacheListener.onCacheProgressChanged(url, 0.0);
                                // }
                            }
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "Error in cache monitoring task for " + url, e);
                        if (flutterCacheListener != null) {
                            flutterCacheListener.onCacheError(url, e.getMessage() != null ? e.getMessage() : "未知监控错误");
                        }
                    }
                }
            }, 0, 1, TimeUnit.SECONDS);

            // 存储任务引用以便后续取消
            monitoringTasks.put(url, task);
        } else {
            Log.w(TAG, "ScheduledExecutorService not available for monitoring " + url);
        }
    }

    private double calculateApproximateProgress(String url, File cacheFile) {
        // AndroidVideoCache 不直接提供总文件大小，这是一个非常粗略的估计
        // 更好的方法是让调用者提供预期的文件大小，或者从HTTP头中获取Content-Length
        // 这里我们只根据文件是否增长来做非常粗略的判断，实际意义不大，除非我们有总大小
        if (cacheFile == null || !cacheFile.exists())
            return 0.0;
        long fileSize = cacheFile.length();

        // 如果我们能以某种方式获取或存储预期的总大小，这里的逻辑会更有用
        // 例如: private final ConcurrentHashMap<String, Long> expectedFileSizes = new
        // ConcurrentHashMap<>();
        // Long totalSize = expectedFileSizes.get(url);
        // if (totalSize != null && totalSize > 0) {
        // return Math.min(1.0, (double) fileSize / totalSize);
        // }

        // 由于没有总大小，我们只能假设它正在下载，并返回一个略微增加的进度，直到它被标记为isCached()
        double currentProgress = cacheProgress.getOrDefault(url, 0.0);
        if (fileSize > 0 && currentProgress < 0.95) { // 如果文件存在且未完成
            // 每次增加一点，但不超过0.95，除非isCached变为true
            return Math.min(currentProgress + 0.05, 0.95);
        }
        return currentProgress; // 如果没有更好的信息，保持当前进度
    }

    private void stopCacheMonitoring(String url) {
        Log.d(TAG, "stopCacheMonitoring called for: " + url);

        // 取消对应URL的监控任务
        ScheduledFuture<?> task = monitoringTasks.remove(url);
        if (task != null && !task.isDone() && !task.isCancelled()) {
            task.cancel(true);
            Log.d(TAG, "Successfully cancelled monitoring task for: " + url);
        }

        // 清理状态
        cacheStatus.remove(url);
        cacheProgress.remove(url);
    }

    private File getCacheFile(String url) {
        try {
            File cacheDir = new File(context.getCacheDir(), "video_cache");
            // 使用与初始化时相同的逻辑获取文件名
            String extension = "mp4";
            int lastDotIndex = url.lastIndexOf('.');
            if (lastDotIndex > 0 && lastDotIndex < url.length() - 1) {
                extension = url.substring(lastDotIndex + 1);
            }
            String fileName = String.valueOf(url.hashCode()) + "." + extension;
            // Log.d(TAG, "getCacheFile for " + url + ", resolved to: " + new File(cacheDir,
            // fileName).getAbsolutePath());
            return new File(cacheDir, fileName);
        } catch (Exception e) {
            Log.e(TAG, "Error in getCacheFile for " + url, e);
            return null;
        }
    }

    private void cleanup() {
        Log.d(TAG, "cleanup called.");
        try {
            // 停止所有正在进行的缓存任务
            for (String url : new HashSet<>(cacheStatus.keySet())) {
                try {
                    Log.d(TAG, "Stopping cache for URL during cleanup: " + url);
                    stopCacheMonitoring(url);
                } catch (Exception e) {
                    Log.e(TAG, "Error stopping cache for " + url + " during cleanup", e);
                }
            }

            // 取消所有监控任务
            for (Map.Entry<String, ScheduledFuture<?>> entry : monitoringTasks.entrySet()) {
                ScheduledFuture<?> task = entry.getValue();
                if (task != null && !task.isDone() && !task.isCancelled()) {
                    task.cancel(true);
                    Log.d(TAG, "Cancelled monitoring task for: " + entry.getKey());
                }
            }
            monitoringTasks.clear();

            // 强制关闭线程池
            if (scheduledExecutor != null) {
                scheduledExecutor.shutdownNow();
                try {
                    if (!scheduledExecutor.awaitTermination(2, java.util.concurrent.TimeUnit.SECONDS)) {
                        Log.w(TAG, "ScheduledExecutor did not terminate gracefully");
                    }
                } catch (InterruptedException e) {
                    Log.w(TAG, "Interrupted while waiting for ScheduledExecutor termination");
                    Thread.currentThread().interrupt();
                }
                Log.d(TAG, "ScheduledExecutorService shut down.");
            }

            // 关闭代理服务器
            if (proxyServer != null) {
                try {
                    proxyServer.shutdown();
                    Log.d(TAG, "HttpProxyCacheServer shut down.");
                } catch (Exception e) {
                    Log.e(TAG, "Error shutting down HttpProxyCacheServer", e);
                }
                proxyServer = null;
            }

            // 清理所有状态
            progressListeners.clear();
            statusListeners.clear();
            cacheStatus.clear();
            cacheProgress.clear();

            Log.d(TAG, "Cleanup completed successfully.");
        } catch (Exception e) {
            Log.e(TAG, "Error during cleanup", e);
        }
    }

    // EventChannel StreamHandler methods
    @Override
    public void onListen(Object arguments, EventSink events) {
        eventSink = events;
    }

    @Override
    public void onCancel(Object arguments) {
        eventSink = null;
    }

    // 发送缓存事件到Flutter
    private void sendCacheEvent(String type, String url, Map<String, Object> data) {
        Log.d(TAG, "Sending cache event to Flutter - Type: " + type + ", URL: " + url + ", Data: " + data.toString());
        Map<String, Object> event = new HashMap<>();
        event.put("type", type);
        event.put("url", url);
        event.putAll(data);

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (eventSink != null) {
                    eventSink.success(event);
                }
            }
        });
    }

    // 辅助方法：递归删除目录
    private void deleteRecursively(File file) {
        Log.d(TAG, "Recursively deleting: " + file.getAbsolutePath());
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                for (File child : children) {
                    deleteRecursively(child);
                }
            }
        }
        file.delete();
    }

    // 辅助方法：计算目录大小
    private long calculateDirectorySize(File directory) {
        // Log.d(TAG, "Calculating size of directory: " + directory.getAbsolutePath());
        long size = 0;
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        size += file.length();
                    } else if (file.isDirectory()) {
                        size += calculateDirectorySize(file);
                    }
                }
            }
        }
        return size;
    }
}